package main

import (
	"errors"
	"fmt"
	"runtime"
)

var ErrDivisionByZero = errors.New("除 0 异常")

func div(a, b int) (int, error) {
	defer func() {
		err := recover()               //panic 消除了，如果你变成要用，就要用变量接收这个值
		fmt.Printf("%T %[1]v \n", err) // any interface{}
		if v, ok := err.(error); ok {
			fmt.Println(v)
		} else {
			fmt.Println("管不了")
		}
	}()
	defer fmt.Println("1 进入 div 了")
	defer fmt.Println(2, a, b)
	defer func() {
		err := recover() // panic要在这里处理
		fmt.Printf("8 %T %[1]v\n", err)
		switch v := err.(type) {
		case nil:
			fmt.Println("没有错误", v)
		case error: // 大类型
			fmt.Println("我是 error 接口类型的", v.Error())
		case runtime.Error: // 小类型
			fmt.Printf("运行时错误, %T %[1]v", v)
		default:
			fmt.Println("其他错误类型，我管不了")
		}
	}()
	r := a / b
	fmt.Println(3, r)
	return r, nil
}

func main() {
	defer func() {
		err := recover()
		fmt.Printf("6 在main中管panic, %v\n", err)
	}()
	if r, err := div(5, 0); err != nil {
		fmt.Println("4 有错误", err.Error())
	} else {
		fmt.Println("5 没有错误", r)
	}
	fmt.Println("7 进程正常结束")

}
